﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MYQQX.SP
{
    public delegate bool CheckSpDelegate(string cardName);

    public abstract class ISp
    {
        public abstract string Name { get; }

        public abstract string Desc { get; }

        /// <summary>
        /// 稀有牌额外分数（要减去原有牌的分数2）
        /// </summary>
        public virtual int SpScore => 2;

        /// <summary>
        /// 是否是被交换
        /// </summary>
        public bool BeChanged { get; set; } = false;

        internal string CardName
        {
            get
            {
                var arr = this.Name.Split('·');
                return arr[0];
            }
        }

        // 是否由AI控制
        public bool AI { get; internal set; }

        /// <summary>
        /// 卡牌的额外分数
        /// </summary>
        public virtual int GetExtraScore(CardGroup group)
        {
            return 0;
        }

        /// <summary>
        /// 入手牌时的触发效果
        /// </summary>
        /// <param name="MyGroup"></param>
        /// <param name="OtGroup"></param>
        public virtual void Got(CardGroup MyGroup, CardGroup OtGroup)
        {

        }

        /// <summary>
        /// 特殊牌移除时触发效果
        ///     - 主要是将一些持续效果给移除
        /// </summary>
        public virtual void Lost()
        { }

        /// <summary>
        /// 换牌操作
        /// </summary>
        /// <param name="MyGroup"></param>
        /// <param name="OtGroup"></param>
        protected virtual void Change(CardGroup MyGroup, CardGroup OtGroup)
        {
            if (AI)
            {
                ChangeForAI(MyGroup, OtGroup);
                return;
            }

            // 换牌操作
            ShowForm frm = new ShowForm(OtGroup);
            frm.Text = "交换卡牌-[请选择一张卡牌！]";
            frm.AllowChoose = true;
            if (frm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                var cCardName = frm.ChooseCard;

                var sp = OtGroup.GetSpCard(cCardName);
                if (sp != null)
                {
                    // 如果对方有对应的稀有牌，这将稀有牌也一起拿过来
                    OtGroup.RemoveSpCard(sp.Name);
                    sp.BeChanged = true; // 稀有牌记录为“被交换”

                    MyGroup.spList.Add(sp);
                }

                // 基础牌
                OtGroup.RemoveCard(cCardName);
                MyGroup.RemoveCard(this.CardName);
                OtGroup.AddCardByName(this.CardName,true);
                OtGroup.AddCardByName(CardName,true);
            }
        }

        protected virtual void ChangeForAI(CardGroup MyGroup, CardGroup OtGroup)
        {
            // 换牌操作 - AI
            var sc = 0;
            Card cd = null;
            string cCardName = "";
            // 1. 优先和自己的卡可以组合的卡
            foreach (var card in OtGroup.cardList)
            {
                var newList = MyGroup.cardList.ToArray().ToList();
                newList.Add(card);

                var m = GroupConfig.Instance.GetGroups(newList)
                    .Where(t => t.groups.Contains(card.Name))
                    .Select(t => t.Score).Sum();
                if (m > sc)
                {
                    sc = m;
                    cd = card;
                }
            }
            if (cd != null)
            {
                cCardName = cd.Name;
            }
            else
            {
                // 2. 没有需要的组合，则查找对方组合用到最多的课
                if (OtGroup.Group.Count > 0)
                {
                    Dictionary<string, int> dic = new Dictionary<string, int>();
                    foreach (var gp in OtGroup.Group)
                    {
                        foreach (var cn in gp.groups)
                        {
                            if (dic.ContainsKey(cn))
                                dic[cn] = dic[cn] + 1;
                            else
                                dic[cn] = 1;
                        }
                    }
                    var mPair = dic.OrderByDescending(t => t.Value).FirstOrDefault();
                    cCardName = mPair.Key;
                }
                else
                {
                    // 3. 对方也没有组合，查找可以触发自己稀有牌的卡
                    var spc = OtGroup.cardList.Where(t => MyGroup.spList.Any(k => k.CardName == t.Name))
                        .FirstOrDefault();
                    if (spc != null)
                    {
                        cCardName = spc.Name;
                    }
                    else
                    {
                        // 4. 还是没有，随机选一张
                        Random rand = new Random(Guid.NewGuid().GetHashCode());
                        Card rc = OtGroup.cardList[rand.Next(OtGroup.cardList.Count)];
                        cCardName = rc.Name;
                    }
                }
            }
            if (!string.IsNullOrEmpty(cCardName))
            {
                var sp = OtGroup.GetSpCard(cCardName);
                if (sp != null)
                {
                    // 如果对方有对应的稀有牌，这将稀有牌也一起拿过来
                    OtGroup.RemoveSpCard(sp.Name);
                    sp.BeChanged = true; // 稀有牌记录为“被交换”

                    MyGroup.spList.Add(sp);
                }

                // 基础牌
                OtGroup.RemoveCard(cCardName);
                MyGroup.RemoveCard(this.CardName);
                OtGroup.AddCardByName(this.CardName, true);
                OtGroup.AddCardByName(CardName, true);
            }
        }

        /// <summary>
        /// 禁用特殊牌技能 - 对方删除对应的特殊牌
        /// </summary>
        /// <param name="myGroup"></param>
        /// <param name="otGroup"></param>
        protected virtual void Disable(CardGroup OtGroup, CheckSpDelegate checkSp = null)
        {
            if (AI)
            {
                DisableForAI(OtGroup, checkSp);
                return;
            }
            ShowXyForm frm = new ShowXyForm(OtGroup);
            frm.Text = "禁用卡牌-[请选择需要禁用的稀有牌]";
            frm.CheckSpAct = checkSp;
            frm.NeedChose = true;
            if (frm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                OtGroup.RemoveSpCard(frm.choseSp.Name);
            }
        }

        private void DisableForAI(CardGroup otGroup, CheckSpDelegate checkSp)
        {
            // 1. 优先禁用有加分技能的
            int sc = 0;
            ISp isp = null;
            List<ISp> uList = new List<ISp>();
            foreach (var sp in otGroup.spList)
            {
                if (checkSp != null
                    && !checkSp.Invoke(sp.CardName))
                {
                    continue;
                }
                uList.Add(sp);
                int num= sp.GetExtraScore(otGroup);
                if (num > sc)
                {
                    sc = num;
                    isp = sp; 
                }
            }
            if (isp != null)
            {
                if (uList.Count > 0)
                {
                    // 2. 无加分，则随机
                    Random rand = new Random(Guid.NewGuid().GetHashCode());
                    isp = uList[rand.Next(uList.Count)];
                }
            }


            if (isp != null)
            {
                otGroup.RemoveSpCard(isp.Name);
            }
        }

        /// <summary>
        /// 复制一张稀有牌技能 - 自己得到相应的特殊牌
        /// </summary>
        /// <param name="OtGroup"></param>
        protected virtual void Copy(CardGroup MyGroup, CardGroup OtGroup)
        {
            if (AI)
            {
                CopyForAI(MyGroup, OtGroup);
                return;
            }
            ShowXyForm frm = new ShowXyForm(OtGroup);
            frm.Text = "复制卡牌-[请选择需要复制技能的稀有牌]";
            frm.NeedChose = true;
            if (frm.ShowDialog() == System.Windows.Forms.DialogResult.OK)
            {
                var sp = frm.choseSp.MemberwiseClone() as ISp;
                sp.BeChanged = true; // 记录为被交换
                MyGroup.spList.Add(sp);
            }
        }

        
        private void CopyForAI(CardGroup MyGroup, CardGroup otGroup)
        {
            // 1. 优先复制有加分技能的
            int sc = 0;
            ISp isp = null;
            foreach (var sp in otGroup.spList)
            {
                int num = sp.GetExtraScore(MyGroup);
                if (num > sc)
                {
                    sc = num;
                    isp = sp;
                }
            }
            if (isp != null)
            {
                // 2. 无加分，则随机
                Random rand = new Random(Guid.NewGuid().GetHashCode());
                isp = otGroup.spList[rand.Next(otGroup.spList.Count)];
            }


            if (isp != null)
            {
                isp.BeChanged = true;
                MyGroup.spList.Add(isp);
            }
        }

        /// <summary>
        /// 翻开对方卡牌
        /// </summary>
        /// <param name="OtGroup"></param>
        /// <param name="Count"></param>
        protected virtual void OpenCard(CardGroup OtGroup, int Count)
        {
            OtGroup.ShowList.OpenCard(Count);
        }

        /// <summary>
        /// 设置下一张牌的出现定义
        /// </summary>
        /// <param name="sendCard"></param>
        protected void SetNextSend(SendCardDelegate sendCard)
        {
            MainForm.NextSend = sendCard;
        }
    }
}
